{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8968a502d25e"
      },
      "source": [
        "##### Copyright 2025 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "cellView": "form",
        "id": "ca23c3f523a7"
      },
      "outputs": [],
      "source": [
        "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wwH5rYtX5Xco"
      },
      "source": [
        "# What's new in Gemini-1.5-pro-002 and Gemini-1.5-flash-002"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "67ad518df45c"
      },
      "source": [
        "<a target=\"_blank\" href=\"https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/New_in_002.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" height=30/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "V4RV6XuQLjCc"
      },
      "source": [
        "This notebook explores the new options added with the 002 versions of the 1.5 series models:\n",
        "\n",
        "* Candidate count\n",
        "* Presence and frequency penalties\n",
        "* Response logprobs"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a5ZjsAuEGK6i"
      },
      "source": [
        "## Setup"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tnl6PeGKOfcA"
      },
      "source": [
        "Install a `002` compatible version of the SDK:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "xVTnXHg_nxMC"
      },
      "outputs": [],
      "source": [
        "%pip install -q \"google-generativeai>=0.8.2\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qLASVngmOm8K"
      },
      "source": [
        "import the package and give it your API-key"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "B6fY-RbxJl78"
      },
      "outputs": [],
      "source": [
        "import google.generativeai as genai"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "sRmN-qzhM47E"
      },
      "outputs": [],
      "source": [
        "from google.colab import userdata\n",
        "genai.configure(api_key=userdata.get('GOOGLE_API_KEY'))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7d-e1KfaOxlJ"
      },
      "source": [
        "Import other packages."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "giN4GuufOu02"
      },
      "outputs": [],
      "source": [
        "from IPython.display import display, Markdown, HTML"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qJO3Cz7UO0Ms"
      },
      "source": [
        "Check available 002 models"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "CTBDsceYMh2S"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "models/bard-lmsys-002\n",
            "models/gemini-1.5-pro-002\n",
            "models/gemini-1.5-flash-002\n",
            "models/gemini-1.5-pro-002-test\n",
            "models/gemini-1.5-flash-002-vertex-global-test\n",
            "models/imagen-3.0-generate-002\n",
            "models/imagen-3.0-generate-002-exp\n"
          ]
        }
      ],
      "source": [
        "for model in genai.list_models():\n",
        "  if '002' in model.name:\n",
        "    print(model.name)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "RCFdQUXsIDcm"
      },
      "outputs": [],
      "source": [
        "model_name = \"models/gemini-1.5-flash-002\"\n",
        "test_prompt=\"Why don't people have tails\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EBiweaL6LLKm"
      },
      "source": [
        "## Quick refresher on `generation_config` [Optional]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "bwwgGRtnLOqJ"
      },
      "outputs": [],
      "source": [
        "model = genai.GenerativeModel(model_name, generation_config={'temperature':1.0})\n",
        "response = model.generate_content('hello', generation_config = genai.GenerationConfig(max_output_tokens=5))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5sDxl0g-LQdx"
      },
      "source": [
        "Note:\n",
        "\n",
        "* Each `generate_content` request is sent with a `generation_config` (`chat.send_message` uses `generate_content`).\n",
        "* You can set the `generation_config` by either passing it to the model's initializer, or passing it in the arguments to `generate_content` (or `chat.send_message`).\n",
        "* Any `generation_config` attributes set in `generate_content` override the attributes set on the model.\n",
        "* You can pass the `generation_config` as either a Python `dict`, or a `genai.GenerationConfig`.\n",
        "* If you're ever unsure about the parameters of `generation_config` check `genai.GenerationConfig`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8Cu9hYM4H8Cz"
      },
      "source": [
        "## Candidate count"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "y_D56ekoO4pd"
      },
      "source": [
        "With 002 models you can now use `candidate_count > 1`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "Ez_8Dm-WMIcp"
      },
      "outputs": [],
      "source": [
        "model = genai.GenerativeModel(model_name)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "v5fwiDPjIAfj"
      },
      "outputs": [],
      "source": [
        "generation_config = dict(candidate_count=2)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "Xr6DXm9_IGEJ"
      },
      "outputs": [],
      "source": [
        "response = model.generate_content(test_prompt, generation_config=generation_config)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xg9Qdl1oPBX9"
      },
      "source": [
        "But note that the `.text` quick-accessor only works for the simple 1-candidate case."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "gxNgE6_SI7az"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Invalid operation: The `response.parts` quick accessor retrieves the parts for a single candidate. This response contains multiple candidates, please use `result.candidates[index].text`.\n"
          ]
        }
      ],
      "source": [
        "try:\n",
        "  response.text # Fails with multiple candidates, sorry!\n",
        "except ValueError as e:\n",
        "  print(e)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HDCqgP7YPHur"
      },
      "source": [
        "With multiple candidates you have to handle the list of candidates yourself:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "b8Ud37EjJCfc"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": "Humans don't have tails because of evolutionary changes over millions of years.  Our primate ancestors had tails, but as humans evolved, the tail gradually disappeared.  The reasons aren't fully understood, but several theories exist:\n\n* **Loss of function:**  As our ancestors transitioned to bipedalism (walking upright), the function of a tail for balance and climbing diminished.  Natural selection favored individuals with smaller, less developed tails, as the energy needed to maintain a tail was no longer offset by its usefulness.  Essentially, it became an energetically expensive feature with little benefit.\n\n* **Genetic changes:**  Mutations affecting genes controlling tail development likely occurred and were favored by natural selection.  These mutations could have caused the tail to become smaller in successive generations until it was completely lost.  The coccyx (tailbone) is a vestigial structure – a remnant of our tailed ancestors.\n\n* **Developmental changes:**  Changes in the timing and regulation of genes involved in embryonic development may have led to the shortening and eventual disappearance of the tail.  The genes that once directed tail growth might have been altered to cease development of a tail at an early stage of embryonic growth.\n\nIt's important to note that these are interconnected factors.  The loss of tail function made it less crucial for survival, and genetic mutations that led to its reduced size and eventual disappearance were then naturally selected for.  The process happened gradually over a long period of evolutionary time.\n",
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": "-------------",
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": "Humans don't have tails because of evolution.  Our ancestors did have tails, but over millions of years of evolution, the tail gradually became smaller and less functional until it was essentially absorbed into the body.  There's no single reason, but rather a combination of factors likely contributed:\n\n* **Loss of Functionality:** As our ancestors became bipedal (walking upright), the tail's primary function for balance and locomotion became less crucial.  Other adaptations, like changes in our skeletal structure and leg musculature, compensated for the loss of the tail's balancing role.\n\n* **Genetic Changes:**  Mutations that affected the genes controlling tail development accumulated over time.  These mutations might have been initially neutral or even slightly advantageous in other ways, and natural selection didn't actively remove them because the tail's importance diminished.\n\n* **Energy Conservation:**  Maintaining a tail requires energy.  As our ancestors transitioned to different environments and lifestyles, the energy cost of maintaining a tail may have become a disadvantage, especially in resource-scarce environments.  Those with less pronounced tails, or even the complete loss of tails, might have had a slight survival and reproductive advantage.\n\n* **Sexual Selection:**  It's possible that at some point, a tailless or nearly tailless phenotype became a desirable trait from a sexual selection perspective.  This is difficult to prove, but it's a factor considered in the evolution of various traits.\n\nIn short, the absence of a tail in humans is a result of a gradual evolutionary process where the tail's usefulness decreased, genetic changes accumulated, and natural selection favored individuals with less prominent tails.  The coccyx, the small bone at the base of our spine, is the remnant of our evolutionary tail.\n",
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/markdown": "-------------",
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "for candidate in response.candidates:\n",
        "  display(Markdown(candidate.content.parts[0].text))\n",
        "  display(Markdown(\"-------------\"))\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2iUxBkmsPYvq"
      },
      "source": [
        "The response contains multiple full `Candidate` objects."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "fOxbI7oSRNV_"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "response:\n",
              "GenerateContentResponse(\n",
              "    done=True,\n",
              "    iterator=None,\n",
              "    result=protos.GenerateContentResponse({\n",
              "      \"candidates\": [\n",
              "        {\n",
              "          \"content\": {\n",
              "            \"parts\": [\n",
              "              {\n",
              "                \"text\": \"Humans don't have tails because of evolutionary changes over millions of years.  Our primate ancestors had tails, but as humans evolved, the tail gradually disappeared.  The reasons aren't fully understood, but several theories exist:\\n\\n* **Loss of function:**  As our ancestors transitioned to bipedalism (walking upright), the function of a tail for balance and climbing diminished.  Natural selection favored individuals with smaller, less developed tails, as the energy needed to maintain a tail was no longer offset by its usefulness.  Essentially, it became an energetically expensive feature with little benefit.\\n\\n* **Genetic changes:**  Mutations affecting genes controlling tail development likely occurred and were favored by natural selection.  These mutations could have caused the tail to become smaller in successive generations until it was completely lost.  The coccyx (tailbone) is a vestigial structure \\u2013 a remnant of our tailed ancestors.\\n\\n* **Developmental changes:**  Changes in the timing and regulation of genes involved in embryonic development may have led to the shortening and eventual disappearance of the tail.  The genes that once directed tail growth might have been altered to cease development of a tail at an early stage of embryonic growth.\\n\\nIt's important to note that these are interconnected factors.  The loss of tail function made it less crucial for survival, and genetic mutations that led to its reduced size and eventual disappearance were then naturally selected for.  The process happened gradually over a long period of evolutionary time.\\n\"\n",
              "              }\n",
              "            ],\n",
              "            \"role\": \"model\"\n",
              "          },\n",
              "          \"finish_reason\": \"STOP\",\n",
              "          \"avg_logprobs\": -0.42928099152225774\n",
              "        },\n",
              "        {\n",
              "          \"content\": {\n",
              "            \"parts\": [\n",
              "              {\n",
              "                \"text\": \"Humans don't have tails because of evolution.  Our ancestors did have tails, but over millions of years of evolution, the tail gradually became smaller and less functional until it was essentially absorbed into the body.  There's no single reason, but rather a combination of factors likely contributed:\\n\\n* **Loss of Functionality:** As our ancestors became bipedal (walking upright), the tail's primary function for balance and locomotion became less crucial.  Other adaptations, like changes in our skeletal structure and leg musculature, compensated for the loss of the tail's balancing role.\\n\\n* **Genetic Changes:**  Mutations that affected the genes controlling tail development accumulated over time.  These mutations might have been initially neutral or even slightly advantageous in other ways, and natural selection didn't actively remove them because the tail's importance diminished.\\n\\n* **Energy Conservation:**  Maintaining a tail requires energy.  As our ancestors transitioned to different environments and lifestyles, the energy cost of maintaining a tail may have become a disadvantage, especially in resource-scarce environments.  Those with less pronounced tails, or even the complete loss of tails, might have had a slight survival and reproductive advantage.\\n\\n* **Sexual Selection:**  It's possible that at some point, a tailless or nearly tailless phenotype became a desirable trait from a sexual selection perspective.  This is difficult to prove, but it's a factor considered in the evolution of various traits.\\n\\nIn short, the absence of a tail in humans is a result of a gradual evolutionary process where the tail's usefulness decreased, genetic changes accumulated, and natural selection favored individuals with less prominent tails.  The coccyx, the small bone at the base of our spine, is the remnant of our evolutionary tail.\\n\"\n",
              "              }\n",
              "            ],\n",
              "            \"role\": \"model\"\n",
              "          },\n",
              "          \"finish_reason\": \"STOP\",\n",
              "          \"index\": 1,\n",
              "          \"avg_logprobs\": -0.4348024821413156\n",
              "        }\n",
              "      ],\n",
              "      \"usage_metadata\": {\n",
              "        \"prompt_token_count\": 7,\n",
              "        \"candidates_token_count\": 660,\n",
              "        \"total_token_count\": 667\n",
              "      },\n",
              "      \"model_version\": \"gemini-1.5-flash-002\"\n",
              "    }),\n",
              ")"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "response"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "g86txlIpW3FE"
      },
      "source": [
        "## Penalties\n",
        "\n",
        "The `002` models expose `penalty` arguments that let you affect the statistics of output tokens."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nw5ZwCCCUR2d"
      },
      "source": [
        "### Presence penalty"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8PeJ2GhBW537"
      },
      "source": [
        "The `presence_penalty` penalizes tokens that have already been used in the output, so it induces variety in the model's output. This is detectible if you count the unique words in the output.\n",
        "\n",
        "Here's a function to run a prompt a few times and report the fraction of unique words (words don't map perfectly to tokens but it's a simple way to see the effect)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "Ecolt7BNHUr2"
      },
      "outputs": [],
      "source": [
        "from statistics import mean"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "1FbjPwM3ZIaH"
      },
      "outputs": [],
      "source": [
        "def unique_words(prompt, generation_config, N=10):\n",
        "  responses = []\n",
        "  vocab_fractions = []\n",
        "  for n in range(N):\n",
        "    model = genai.GenerativeModel(model_name)\n",
        "    response = model.generate_content(contents=prompt, generation_config=generation_config)\n",
        "    responses.append(response)\n",
        "\n",
        "    words = response.text.lower().split()\n",
        "    score = len(set(words))/len(words)\n",
        "    print(score)\n",
        "    vocab_fractions.append(score)\n",
        "\n",
        "  return vocab_fractions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "n2PqpDPIZpr6"
      },
      "outputs": [],
      "source": [
        "prompt='Tell me a story'"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "6GTXnUVlYyY9"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.5698689956331878\n",
            "0.5426008968609866\n",
            "0.6184834123222749\n",
            "0.55741127348643\n",
            "0.6084070796460177\n",
            "0.545054945054945\n",
            "0.5891304347826087\n",
            "0.5920398009950248\n",
            "0.5663716814159292\n",
            "0.5831485587583148\n"
          ]
        }
      ],
      "source": [
        "# baseline\n",
        "v = unique_words(prompt, generation_config={})"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "id": "ZwFZBP68wKp3"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.577251707895572"
            ]
          },
          "execution_count": 19,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "mean(v)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "id": "DlM8BVflUpAj"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.6214833759590793\n",
            "0.5617529880478087\n",
            "0.5894495412844036\n",
            "0.5789473684210527\n",
            "0.5781990521327014\n",
            "0.6389684813753582\n",
            "0.6061320754716981\n",
            "0.5727482678983834\n",
            "0.5864485981308412\n",
            "0.565410199556541\n"
          ]
        }
      ],
      "source": [
        "# the penalty encourages diversity in the oputput tokens.\n",
        "v = unique_words(prompt, generation_config=dict(presence_penalty=1.999))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "id": "HJo-_6_owQfu"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.5899539948277868"
            ]
          },
          "execution_count": 21,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "mean(v)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "id": "G-CztHdqTc__"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.5555555555555556\n",
            "0.6472148541114059\n",
            "0.5839598997493735\n",
            "0.6132075471698113\n",
            "0.5858369098712446\n",
            "0.5823389021479713\n",
            "0.5895691609977324\n",
            "0.5978021978021978\n",
            "0.5604166666666667\n",
            "0.5741626794258373\n"
          ]
        }
      ],
      "source": [
        "# a negative penalty discourages diversity in the output tokens.\n",
        "v = unique_words(prompt, generation_config=dict(presence_penalty=-1.999))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "id": "x1eWaOAOwWrE"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.5890064373497796"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "mean(v)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nA7LkwvBMCjd"
      },
      "source": [
        "The `presence_penalty` has a small effect on the vocabulary statistics."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "c_Anpg6YRPEx"
      },
      "source": [
        "### Frequency Penalty"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "P-m1BaNuXVoY"
      },
      "source": [
        "Frequency penalty is similar to the `presence_penalty` but  the penalty is multiplied by the number of times a token is used. This effect is much stronger than the `presence_penalty`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IZw9D5ZvWnmq"
      },
      "source": [
        "The easiest way to see that it works is to ask the model to do something repetitive. The model has to get creative while trying to complete the task."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "id": "Ju9AIzBJ_-dR"
      },
      "outputs": [],
      "source": [
        "model = genai.GenerativeModel(model_name)\n",
        "response = model.generate_content(contents='please repeat \"Cat\" 50 times, 10 per line',\n",
        "                                  generation_config=dict(frequency_penalty=1.999))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "id": "O9eixhvwS6It"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Cat Cat Cat Cat Cat Cat Cat Cat Cat Cat\n",
            "Cat Cat Cat Cat Cat Cat Cat Cat CaT CaT\n",
            "Cat cat cat cat cat cat cat cat cat cat\n",
            "Cat Cat Cat Cat Cat Cat Cat Cat Cat Cat\n",
            "Cat Cat Cat Cat Cat Cat Cat CaT CaT CaT\n",
            "Cat cat cat cat cat cat cat cat cat cat\n",
            "Cat Cat Cat Cat Cat Cat Cat CaT CaT CaT\n",
            "Cat CAT CAT CAT CAT CAT cAT cAT cAT CA\n",
            "t Cat Cat Cat Cat cat cat cat cat CAT\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(response.text)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6HMQhl2bJnk1"
      },
      "source": [
        "Since the frequency penalty accumulates with usage, it can have a much stronger effect on the output compared to the presence penalty.\n",
        "\n",
        "> Caution: Be careful with negative frequency penalties: A negative penalty makes a token more likely the more it's used. This positive feedback quickly leads the model to just repeat a common token until it hits the `max_output_tokens` limit (once it starts the model can't produce the `<STOP>` token)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "metadata": {
        "id": "48HdqCUK2oT9"
      },
      "outputs": [],
      "source": [
        "response = model.generate_content(\n",
        "    prompt,\n",
        "    generation_config=genai.GenerationConfig(\n",
        "        max_output_tokens=400,\n",
        "        frequency_penalty=-2.0))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "id": "2QpGQoHU27zK"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": "Elara, a wisp of a girl with eyes the colour of a stormy sea, lived in a lighthouse perched precariously on the edge of the Whispering Cliffs.  Her only companions were the relentless rhythm of the waves and the lonely cries of the gulls.  Her father, the lighthouse keeper, was a man of the sea, his face etched with the map of the ocean's moods.  He’d taught her the language of the waves, the the the the way the wind whispered secrets to the rocks, and the constellations that guided lost ships home.\n\nOne day, a storm unlike any Elara had ever seen descended.  The lighthouse shuddered, the wind howled like a banshee, and the waves crashed against the cliffs with the fury of a thousand angry giants.  During the tempest, a ship, its masts splintered and its sails ripped, was tossed onto the rocks below.  Elara’s father, his face grim, prepared his small, sturdy boat, defying the monstrous waves to reach the stricken vessel.\n\nHe never returned.\n\nDays bled into weeks.  Elara, her heart a frozen wasteland, kept the light burning, a tiny, defiant flame against the overwhelming darkness.  She scanned the horizon every day, hoping, praying, for a sign, a glimpse of a familiar sail, a flicker of a known light.\n\nOne evening, a faint, almost imperceptible glow appeared on the horizon.  It was weak, flickering, but undeniably there.  It was a signal, a desperate plea for help.  Elara, her heart pounding, launched her father’s boat, her small form a mere speck against the immensity of the ocean.\n\nThe storm, though, had subsided.  The sea was calm. The glow was guiding.\n\nShe reached the ship, a small fishing trawler, battered, but afloat.  A lone figure, an old woman with silver hair, lay clinging to the",
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "execution_count": 27,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "Markdown(response.text)  # the, the, the, ..."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {
        "id": "tmntZO3gNt6r"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<FinishReason.MAX_TOKENS: 2>"
            ]
          },
          "execution_count": 28,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "response.candidates[0].finish_reason"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "New_in_002.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
